package us.proyecto.canarios.actions.concursos;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.log.Log;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
import org.richfaces.component.html.HtmlTree;
import org.richfaces.event.NodeSelectedEvent;
import org.richfaces.model.TreeNode;

import us.proyecto.canarios.actions.admin.AutenticacionAction;
import us.proyecto.canarios.dao.ConcursoDAO;
import us.proyecto.canarios.dao.DiccionarioDAO;
import us.proyecto.canarios.dao.PajarosDAO;
import us.proyecto.canarios.dao.UsuarioDAO;
import us.proyecto.canarios.domain.Asociacion;
import us.proyecto.canarios.domain.Concurso;
import us.proyecto.canarios.domain.Criador;
import us.proyecto.canarios.domain.Incidencia;
import us.proyecto.canarios.domain.Pajaro;
import us.proyecto.canarios.domain.Puntuacion;
import us.proyecto.canarios.domain.Tipo;
import us.proyecto.canarios.domain.Usuario;

@Name("consultaCanarioCriador")
@Scope(ScopeType.SESSION)
public class ConsultaCanarioCriadorAction {

	@Logger
	Log log;

	private String nombre;
	private Asociacion asociacion;
	private Date fechaInicio;
	private Date fechaFin;

	@In(create = true)
	private UsuarioDAO usuarioDAO;



	private List<Tipo> listaTipos;

	private List<Asociacion> listaAsociaciones;


	private List<Puntuacion> listaConcursos;

	@In(create = true)
	private ConcursoDAO concursoDAO;

	@In(create = true)
	private DiccionarioDAO diccionariosDAO;

	@In(create = true)
	private PajarosDAO pajarosDAO;

	private List<Criador> listaCriadores;

	private Puntuacion puntuacion;

	@In
	private Usuario user;

	private Concurso concurso;

	@In(create = true)
	private AutenticacionAction autenticacion;

	@In(create = true)
	private ConsultaPajarosCriadorAction gestionCanarioCriador;

	@In(create = true)
	private GestionConcursoCriadorAction gestionConcursoCriador;

	@In(create = true)
	private ConsultaBDAction gestionBD;

	// private Tipo tipo;

	private Pajaro pajaro;

	private List<Incidencia> listaIncidencias;


	private byte[] grafica;

	private Boolean mostrarPun;

	private boolean consulta;

	private Criador criador;

	private String mensaje;

	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public void buscar() {
		String where = new String(" 1 = 1 ");
		where = where + " and c.asociacion.idAsociacion = "
				+ user.getAsociacion().getIdAsociacion();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date d = new Date();
		where = where + " and c.fechaInicio <= convert('" + sdf.format(d)
				+ " ', DATE) ";
		where = where + " and c.fechaFin >= convert('" + sdf.format(d)
				+ " ', DATE) ";
		//listaConcursosAsoc = concursoDAO.getListByWhere(where);

	}


	public String traduce(String s) {
		String res = "";
		if (s.equals("true")) {
			res = "Si";
		} else {
			res = "No";
		}
		return res;

	}

	public void gestion() {
		pajaro = new Pajaro();
		puntuacion = new Puntuacion();
		puntuacion.setPajaro(pajaro);
		pajaro.setPuntuaciones(new HashSet<Puntuacion>());
		pajaro.getPuntuaciones().add(puntuacion);
		listaCriadores = usuarioDAO.getCriadores();
		buscar();

	}

	@Begin(join = true, flushMode=FlushModeType.MANUAL)
	public String gestion(Concurso con) {
		if(con.getIdConcurso()!=0){
			concurso = con;
			pajaro = new Pajaro();
			puntuacion = new Puntuacion();
			puntuacion.setPajaro(pajaro);
			puntuacion.setConcurso(con);
			pajaro.setPuntuaciones(new HashSet<Puntuacion>());
			pajaro.getPuntuaciones().add(puntuacion);
			listaCriadores = usuarioDAO.getCriadores();
			puntuacion.setNumJaula(concursoDAO.obtieneNumJaula(concurso));
			crearGrafica();
			buscar();
			return "true";
		}
		return "false";

	}

	/**
	 * @return the asociacion
	 */
	public Asociacion getAsociacion() {
		return asociacion;
	}

	/**
	 * @param asociacion
	 *            the asociacion to set
	 */
	public void setAsociacion(Asociacion asociacion) {
		this.asociacion = asociacion;
	}

	/**
	 * @return the fechaInicio
	 */
	public Date getFechaInicio() {
		return fechaInicio;
	}

	/**
	 * @param fechaInicio
	 *            the fechaInicio to set
	 */
	public void setFechaInicio(Date fechaInicio) {
		this.fechaInicio = fechaInicio;
	}

	/**
	 * @return the fechaFin
	 */
	public Date getFechaFin() {
		return fechaFin;
	}

	/**
	 * @param fechaFin
	 *            the fechaFin to set
	 */
	public void setFechaFin(Date fechaFin) {
		this.fechaFin = fechaFin;
	}


	/**
	 * @return the listaAsociaciones
	 */
	public List<Asociacion> getListaAsociaciones() {
		return listaAsociaciones;
	}

	/**
	 * @param listaAsociaciones
	 *            the listaAsociaciones to set
	 */
	public void setListaAsociaciones(List<Asociacion> listaAsociaciones) {
		this.listaAsociaciones = listaAsociaciones;
	}

	public List<Tipo> getListaTipos() {
		if (listaTipos == null) {
			listaTipos = diccionariosDAO.getListaTipos();
		}
		return listaTipos;
	}

	public void setListaTipos(List<Tipo> listaTipos) {
		this.listaTipos = listaTipos;
	}

	public Usuario getUser() {
		return user;
	}

	public void setUser(Usuario usuario) {
		this.user = usuario;
	}

	public Concurso getConcurso() {
		return concurso;
	}

	public void setConcurso(Concurso concurso) {
		this.concurso = concurso;
	}

	/*
	 * public Tipo getTipo() { return tipo; }
	 *
	 * public void setTipo(Tipo tipo) { this.tipo = tipo; }
	 */


	public void cambiarConcurso() {
		puntuacion.setConcurso(concurso);
		if (pajaro.getPuntuaciones() != null && concurso != null) {
			boolean enc = false;
			for (Puntuacion pun : pajaro.getPuntuaciones()) {
				if (pun.getConcurso().getIdConcurso() == concurso
						.getIdConcurso()) {
					puntuacion = pun;
					enc = true;
				}
			}
			if (!enc) {
				puntuacion = new Puntuacion();
				puntuacion.setPajaro(pajaro);
				puntuacion.setConcurso(concurso);
				pajaro.getPuntuaciones().add(puntuacion);
			}
		}
	}

	public void buscarPajaro() {
		Pajaro p = pajarosDAO.getPajaroByNumAnilla(pajaro.getNumAnilla());
		Pajaro aux = pajaro;
		Puntuacion punt = puntuacion;
		pajaro = p;
		if (pajaro != null && pajaro.getPuntuaciones() != null
				&& concurso != null) {
			boolean enc = false;
			for (Puntuacion pun : pajaro.getPuntuaciones()) {
				if (pun.getConcurso() != null && pun.getConcurso().getIdConcurso() == concurso
						.getIdConcurso()) {
					FacesMessages
							.instance()
							.add("Este pajaro ya se ha dado de alta en el concurso, sus datos solo se actualizarán");
					puntuacion = pun;
					enc = true;
				}
			}
			if (!enc) {
				puntuacion = new Puntuacion();
				puntuacion.setPajaro(pajaro);
				puntuacion.setConcurso(concurso);
				pajaro.getPuntuaciones().add(puntuacion);
			}
		} else {
			pajaro = aux;
			puntuacion = punt;
			//puntuacion.setPajaro(pajaro);
			//puntuacion.setConcurso(concurso);
			//pajaro.setPuntuaciones(new HashSet<Puntuacion>());
			//pajaro.getPuntuaciones().add(puntuacion);
		}
	}

	public void guardar() {
		// pajaro.getPuntuaciones().add(puntuacion);
		if (pajaro.getIdPajaro() == 0) {
			pajarosDAO.save(pajaro);
		} else {
			pajarosDAO.update(pajaro);
		}

	}

	public void guardarIncidencia() {
		// pajaro.getPuntuaciones().add(puntuacion);
		puntuacion.setIncidencias(new HashSet<Incidencia>());
		Incidencia c = listaIncidencias.get(listaIncidencias.size()-1);
		listaIncidencias.remove(listaIncidencias.size()-1);
		puntuacion.getIncidencias().addAll(listaIncidencias);
		listaIncidencias.add(c);
		if (pajaro.getIdPajaro() == 0) {
			pajarosDAO.save(pajaro);
		} else {
			pajarosDAO.update(pajaro);
		}

	}

	public void guardarAnadir() {
		// pajaro.getPuntuaciones().add(puntuacion);
		if (pajaro.getIdPajaro() == 0) {
			pajarosDAO.save(pajaro);
		} else {
			pajarosDAO.update(pajaro);
		}
		Criador c = pajaro.getCriador();
		gestion(concurso);
		pajaro.setCriador(c);



	}

	public List<Criador> getListaCriadores() {
		return listaCriadores;
	}

	public void setListaCriadores(List<Criador> listaCriadores) {
		this.listaCriadores = listaCriadores;
	}

	public Pajaro getPajaro() {
		return pajaro;
	}

	public void setPajaro(Pajaro pajaro) {
		this.pajaro = pajaro;
	}

	public Puntuacion getPuntuacion() {
		return puntuacion;
	}

	public void setPuntuacion(Puntuacion puntuacion) {
		this.puntuacion = puntuacion;
	}

	public String processSelection(NodeSelectedEvent event) {
		HtmlTree tree = (HtmlTree) event.getComponent();
		TreeNode currentNode = tree.getModelTreeNode(tree.getRowKey());
		if (currentNode.isLeaf()) {
			Concurso c = (Concurso) currentNode.getData();
			concurso = c;
			pajaro = new Pajaro();
			puntuacion = new Puntuacion();
			puntuacion.setPajaro(pajaro);
			pajaro.setPuntuaciones(new HashSet<Puntuacion>());
			pajaro.getPuntuaciones().add(puntuacion);
			listaCriadores = usuarioDAO.getCriadores();
			buscar();
			return "true";
		} else {
			return "false";
		}
	}

	public void selectPajaro(){
		pajaro = gestionCanarioCriador.getListaPajarosCriador().get(gestionCanarioCriador.getIndex());
		listaConcursos = pajarosDAO.getPuntuacionesPajaro(pajaro);
		puntuacion=null;
		mostrarPun = false;
		consulta = false;
		crearGrafica();
	}

	public void selectPajaroCon(){
		pajaro = gestionConcursoCriador.getPuntuacion().getPajaro();
		puntuacion = gestionConcursoCriador.getPuntuacion();
		mostrarPun = true;
		consulta = false;
		listaConcursos = pajarosDAO.getPuntuacionesPajaro(pajaro);
		crearGrafica();
	}


	public void selectPajaroCons(){
		pajaro = gestionBD.getListaPajarosCriador().get(gestionCanarioCriador.getIndex());
		listaConcursos = pajarosDAO.getPuntuacionesPajaro(pajaro);
		puntuacion=null;
		consulta = true;
		mostrarPun = false;
		criador = pajaro.getCriador();
		mensaje = null;
		crearGrafica();
	}


	public List<Incidencia> getListaIncidencias() {
		return listaIncidencias;
	}

	public void setListaIncidencias(List<Incidencia> listaIncidencias) {
		this.listaIncidencias = listaIncidencias;
	}

	public void annadir(){
		Incidencia nueva2 =listaIncidencias.get(listaIncidencias.size()-1);
		nueva2.setNueva(false);
		Incidencia nueva = new Incidencia();
		nueva.setNueva(true);
		nueva.setFecha(new Date());
		nueva.setObservaciones("");
		nueva.setPuntuacion(puntuacion);
		listaIncidencias.add(nueva);
	}

	public byte[] getGrafica() {
		return grafica;
	}

	public void setGrafica(byte[] grafica) {
		this.grafica = grafica;
	}


	public void crearGrafica(){
		DefaultCategoryDataset categorydataset = new DefaultCategoryDataset();
		List<Puntuacion> listaCon = pajarosDAO.getPuntuacionesPajaro(pajaro);
		if(listaCon!= null){
			for(Puntuacion p:listaCon){
			    if(p.getPuntuacion()!= null){
				categorydataset.addValue(Double.parseDouble(p.getPuntuacion()),"Puntuaciones", p.getConcurso().getNombre());
			}}
		}
		 JFreeChart chart = ChartFactory.createBarChart("Bar Chart Demo 8", "Category", "Value", categorydataset, PlotOrientation.VERTICAL, false, true, false);
	        CategoryPlot categoryplot = (CategoryPlot)chart.getPlot();
	        NumberAxis numberaxis = (NumberAxis)categoryplot.getRangeAxis();
	        numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
	        numberaxis.setUpperMargin(0.14999999999999999D);
	        CategoryItemRenderer categoryitemrenderer = categoryplot.getRenderer();
	        categoryitemrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
	        categoryitemrenderer.setSeriesItemLabelsVisible(0, Boolean.TRUE);
	        CategoryAxis categoryaxis = categoryplot.getDomainAxis();
	        categoryaxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
	        try {
                grafica = ChartUtilities.encodeAsPNG(chart.createBufferedImage(800, 500));
            } catch (IOException e) {
                System.err.println("Problem occurred creating chart.");
            }
	}

	public List<Puntuacion> getListaConcursos() {
		return listaConcursos;
	}

	public void setListaConcursos(List<Puntuacion> listaConcursos) {
		this.listaConcursos = listaConcursos;
	}

    public Boolean getMostrarPun() {
        return mostrarPun;
    }

    public void setMostrarPun(Boolean mostrarPun) {
        this.mostrarPun = mostrarPun;
    }

	public boolean isConsulta() {
		return consulta;
	}

	public void setConsulta(boolean consulta) {
		this.consulta = consulta;
	}

	public Criador getCriador() {
		return criador;
	}

	public void setCriador(Criador criador) {
		this.criador = criador;
	}

	public String getMensaje() {
		return mensaje;
	}

	public void setMensaje(String mensaje) {
		this.mensaje = mensaje;
	}

	public void enviar(){
		String texto;
        String subject;
        SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");
        Date date = new Date();

        try {
                String fecha = formato.format(date);

                texto = "<h1>"
                                + "<span style='font-family: arial,helvetica,sans-serif;'>"
                                + "Canarios"
                                + "</span>"
                                + "</h1>"
                                + "<h4>"
                                + "Contacto.<"
                                + "/h4>"
                                + "<p>"
                                + mensaje
                                + "</p>"
                                ;

                subject = "Interesado";

                EnviarMail(subject, texto);
        } catch (Exception e) {
                FacesMessages.instance().add(
                                "No se pudo enviar el mail de aviso");
        }
        FacesMessages.instance().add(
                    "Se ha enviado el e-mail al criador correctamente");
	}

	private void EnviarMail(String subject, String texto) {

        Properties props = new Properties();

        String servidorSmtp = ResourceBundle.getBundle("mail").getString(
                        "mail.smtp.host");
        String tls = ResourceBundle.getBundle("mail").getString(
                        "mail.smtp.starttls.enable");
        String puerto = ResourceBundle.getBundle("mail").getString(
                        "mail.smtp.port");
        String usuarioSMTP = ResourceBundle.getBundle("mail").getString(
                        "mail.smtp.user");
        String aunteticacion = ResourceBundle.getBundle("mail").getString(
                        "mail.smtp.auth");
        String pass = ResourceBundle.getBundle("mail").getString("mail.pass");
        String from = ResourceBundle.getBundle("mail").getString("mail.from");

        // Nombre del host de correo, es smtp.gmail.com
        props.setProperty("mail.smtp.host", servidorSmtp);

        // TLS si está disponible
        props.setProperty("mail.smtp.starttls.enable", tls);

        // Puerto de gmail para envio de correos
        props.setProperty("mail.smtp.port", puerto);

        // Nombre del usuario
        props.setProperty("mail.smtp.user", usuarioSMTP);

        // Si requiere o no usuario y password para conectarse.
        props.setProperty("mail.smtp.auth", aunteticacion);

        Session session = Session.getDefaultInstance(props);
        session.setDebug(true);

        MimeMessage message = new MimeMessage(session);

        try {

                // Quien envia el correo
                message.setFrom(new InternetAddress(from));

                boolean continuar = true;
                String email = "";
                if(criador!=null){
                	email = criador.getEmail();
                }
                // A quien va dirigido
                if(email!= null && !email.equals("")){
                	message.addRecipient(Message.RecipientType.TO, new InternetAddress(
                	email));
                }else{
                	continuar = false;
                }

                // Establecemos el asunto
                message.setSubject(subject);
                // añadimos el texto en formato web
                message.setText(texto, "ISO-8859-1", "html");

                Transport t = session.getTransport("smtp");

                if(continuar){
	                t.connect(usuarioSMTP, pass);
	                t.sendMessage(message, message.getAllRecipients());
	                t.close();
                }else{
                	FacesMessages
                    .instance()
                    .add("No has seleccionado una dirección de correo válida)");
                }

        } catch (AddressException e) {
                FacesMessages
                                .instance()
                                .add(
                                                "No se pudo enviar email de notificación (dirección incorrecta)");
                e.printStackTrace();
        } catch (MessagingException e) {
                FacesMessages.instance().add(
                                "No se pudo enviar email de notificación");
                // TODO Auto-generated catch block
                e.printStackTrace();
        }

}

}
